#ifndef OBJECT_H
#define OBJECT_H

#ifndef GENESIS_DATATYPES
#define GENESIS_DATATYPES
typedef unsigned char byte;
typedef unsigned short word;
#endif

#define setobjvariableword(var,obj,value) obj.Variables[var-0x28]=((value&0xFF00)>>8); obj.Variables[(var-0x28)+1]=(value&0x00FF);
#define getobjvariableword(var,obj) (((obj.Variables[var-0x28])<<8)+(obj.Variables[(var-0x28)+1]))
#define addobjvariableword(var,obj,value) setobjvariableword(var,obj,getobjvariableword(var,obj)+1)
#define subobjvariableword(var,obj,value) setobjvariableword(var,obj,getobjvariableword(var,obj)-1)

#define ptrsetobjvariableword(var,obj,value) obj->Variables[var-0x28]=((value&0xFF00)>>8); obj->Variables[(var-0x28)+1]=(value&0x00FF);
#define ptrgetobjvariableword(var,obj) (((obj->Variables[var-0x28])<<8)+(obj->Variables[(var-0x28)+1]))
#define ptraddobjvariableword(var,obj,value) ptrsetobjvariableword(var,obj,ptrgetobjvariableword(var,obj)+1)
#define ptrsubobjvariableword(var,obj,value) ptrsetobjvariableword(var,obj,ptrgetobjvariableword(var,obj)-1)

#define ptrsetobjvariablelong(var,obj,value) ptrsetobjvariableword(var, obj, (value&0xFFFF0000)>>16); ptrsetobjvariableword(var+2, obj, (value&0xFFFF)); 
#define ptrgetobjvariablelong(var,obj) (ptrgetobjvariableword(var, obj)<<16)+(ptrgetobjvariableword(var+2, obj)) 
#define ptraddobjvariablelong(var,obj,value) ptrsetobjvariablelong(var,obj,ptrgetobjvariablelong(var,obj)+1)
#define ptrsubobjvariablelong(var,obj,value) ptrsetobjvariablelong(var,obj,ptrgetobjvariablelong(var,obj)-1)


void pcObjectMethods();
void ExecuteObjects();



struct object
{
    union
    {
        struct { 
        byte ID;
        byte Render;
        word Gfx;   //pointer to VRAM in ROM, since vram is emulated refer to offset as normal word(non-pointer)
        byte **Map;  //long pointer in ROM
        union { long Xdec; struct { word ScreenY; word X; }; };
	union { long Ydec; struct { word Yfract; word Y; }; };
	union { signed short VelocityX; struct { byte VelocityXfract; byte VelocityXdist; }; };
	union { signed short VelocityY; struct { byte VelocityYfract; byte VelocityYdist; }; };
		signed short Inertia;
		byte Height;
		byte Width;
		byte Priority;
		byte ActionWidth;
		byte Frame;
		byte AniFrame;
		byte Anim;
		byte NextAni;
		signed char TimeFrame;
		byte DelayAni;
		byte ColType;
		byte ColProp;
		byte Status;
		byte RespawnNo;
		byte Routine;
		union { byte secondRoutine; byte Solid; };
		signed short Angle;
		byte Subtype;
		byte Variables[24];
		/*void init(byte i) {  ID=i; }
		bool exists() { return (ID != 0); }
		bool empty() { return (ID == 0); }
		object() { ID=0; }*/
        };
        byte bytes[64];
    };    };    		

#define DeleteChild DeleteObject
void DeleteObject(object *obj);

void SpeedToPos(object *obj);
void ObjectFall(object *obj);
signed short ObjFloorDist(object *obj);
signed short ObjFloorDist(object *obj, word obX);
signed short ObjFloorDist(object *obj, byte &angle);
void SmashObject(object *obj, byte *fragData, long fragCount, word smashSpeed);

#endif
